package ext.tianma.part.imported;

import java.lang.reflect.InvocationTargetException;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;

import wt.fc.Identified;
import wt.fc.IdentityHelper;
import wt.fc.PersistenceHelper;
import wt.fc.PersistenceServerHelper;
import wt.fc.QueryResult;
import wt.method.RemoteAccess;
import wt.method.RemoteMethodServer;
import wt.part.Source;
import wt.part.WTPart;
import wt.part.WTPartMaster;
import wt.part.WTPartMasterIdentity;
import wt.part.WTPartStandardConfigSpec;
import wt.query.QueryException;
import wt.session.SessionServerHelper;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
import wt.vc.config.ConfigHelper;
import wt.vc.views.View;
import wt.vc.views.ViewException;
import wt.vc.views.ViewHelper;
import ext.com.core.CoreUtil;
import ext.com.iba.IBAUtil;
import ext.com.workflow.WorkflowUtil;
import ext.tianma.part.forms.TMTypeUtil;

public class UpdatePartsByIBA implements RemoteAccess {
	private static final String CLASSNAME = UpdatePartsByIBA.class.getName() ;
	//物料描述
	private static final String PART_DESCRIPTION = "partDescription";
	
	private static final int INDEXT_VIEW = 3;
	//产品分级
	private static final String PRODUCT_CLASS_DESC = "productClassDesc";
	//进料检验方式
	private static final String PART_IMCOMING = "partIncomingInspection";

	
	/**
	 * 导入Excel文件中的物料数据
	 * 
	 * @param excelFile
	 */
	public static void updatePartAttributes(String excelFile){
		
		//获取Excel文件的第一个sheet页
		Sheet sheet = ImportedExcelUtil.getFirstSheet( excelFile ) ;
		
		boolean flag = SessionServerHelper.manager.setAccessEnforced(false);
		try{
			updatePartAttributes( sheet ) ;
		}finally{
			SessionServerHelper.manager.setAccessEnforced( flag );
		}
	}

	/**
	 * 导入指定Sheet中的物料数据
	 * 
	 * @param sheet
	 * @return
	 */
	public static StringBuffer updatePartAttributes( Sheet sheet ){
		
		StringBuffer logInfo = new StringBuffer("") ;
		
		if( sheet == null ){
			System.out.println( "Debug   sheet...null" );
			return logInfo ;
		}
		
		try {
			
			//获取表头内部值
			Map<Integer,String> internalNameMap = getColumnInternalNameMap( sheet ) ;
			//获取表头显示名称
			Map<Integer,String> displayNameMap = getColumnDisplayNameMap( sheet ) ;
				
			//遍历行数据，每行对应一个料号的物料
			Iterator<Row> rowIte = sheet.rowIterator() ;
			while( rowIte.hasNext() ){
				Row row = rowIte.next() ;
					
				if( row != null ){
					int rowIndex = row.getRowNum() ;
						
					int rowNum = rowIndex + 1 ;
					System.out.println(">>>>> Start Process Row " + rowNum ) ;
						
					if( rowIndex >= ImportConstants.DATA_START_ROW_INDEX ){							
						//按行导入物料更新物料属性
						updatePartAttributes( row ,internalNameMap , displayNameMap , logInfo ) ;
					}
					
					System.out.println(">>>>> End Process Row " + rowNum ) ;
				}
			}
		} catch (QueryException e) {
			e.printStackTrace();
		} catch (WTException e) {
			e.printStackTrace();
		} catch (RemoteException e) {
			e.printStackTrace();
		} finally{
			System.out.println( logInfo ) ;
		}

		return logInfo ;
	}
	
	/**
	 * 按行导入物料的数据，每行物料对应一个料号的零部件
	 * 
	 * @param row Excel文件的行
	 * @param container 导入物料的库 
	 * @param internalNameMap
	 * @param displayNameMap
	 * @param logInfo
	 * 
	 * @throws WTException
	 * @throws RemoteException
	 */
	private static void updatePartAttributes( Row row ,  Map<Integer,String> internalNameMap , Map<Integer,String> displayNameMap , StringBuffer logInfo ) throws WTException, RemoteException {
		if( row ==null ){
			return ;
		}
		
		//获取料号
		String partNumber = ImportedExcelUtil.getCellValueByIndex(row, ImportConstants.PART_NUMBER_COLUMN_INDEX, true) ;
		System.out.println( "Debug   updatePartAttributes...partNumber = " + partNumber );
		if( partNumber != null && ! partNumber.trim().isEmpty() ){
			WTPart dPart = CoreUtil.getWTPartByNumberAndView( partNumber , ImportConstants.D_VIEW ) ;
			
			if( dPart != null ){
				System.out.println( "Debug   updatePartAttributes...dPart = "+dPart.getDisplayIdentity() + "..." + TMTypeUtil.isRawMaterial( dPart ) );
				updatePartAttributes( dPart , row ,  internalNameMap , displayNameMap , logInfo);	
			}		
		}
	}

	private static void updatePartAttributes( WTPart dPart , Row row , Map<Integer, String> internalNameMap , Map<Integer, String> displayNameMap , StringBuffer logInfo ) throws ViewException, WTException {
		
		if( dPart == null || internalNameMap == null || displayNameMap == null ){
			return ;
		}
		//设置原材料“Design”视图的“物料说明”属性
		dPart = updatePartAttributes( row , dPart , internalNameMap , logInfo );
		//获取系统中所有的视图
		View[] views = ViewHelper.service.getAllViews();
		
		if( views != null && views.length > 0 ){
			
			for( int i = 0 ; i < views.length ; i++ ){
				
				if( views[i] != null ){
					//设置原材料除“Design”视图的其他视图的“物料说明”属性
					WTPart part = getWTPartByMasterAndView( ( WTPartMaster )dPart.getMaster(), views[i] );
					
					if( part != null && ( ! part.getViewName().equals( ImportConstants.D_VIEW ) ) ){
						
						updatePartAttributes( row , part , internalNameMap , logInfo );
					}
				}
			}
		}		
	}
	
	
	/**
	 * 保存设置视图版本零部件的属性值
	 * 
	 * @param row
	 * @param part
	 * @param internalNameMap
	 * @param logInfo
	 * @return
	 * @throws WTException
	 */
	private static WTPart updatePartAttributes (Row row , WTPart part , Map<Integer, String> internalNameMap, StringBuffer logInfo)throws WTException {
		
		Iterator<Cell> cellIte = row.cellIterator() ;
		
		if( !WorkflowUtil.isObjectCheckedOut( part ) ){
			part = ( WTPart )CoreUtil.checkoutObject( part );
		} 
		//物料描述
		String partDescription = "";
		//原材料产品分级
		String productClassDesc = "";
		//检验方式
		String partIncomingInspection = "";
		
		while( cellIte.hasNext() ){
			Cell cell = cellIte.next() ;
			
			int cellColumnIndex = cell.getColumnIndex() ;

			String attributeId = internalNameMap.get( cellColumnIndex ) ;
			String attributeValue = ImportedExcelUtil.getCellValueAsString(cell,true) ;
			
			System.out.println( "Debug   updateRawMaterialPartAttributes...attributeId = " + attributeId );
			
			System.out.println( "Debug   updateRawMaterialPartAttributes...attributeValue = " + attributeValue );
			
			if( attributeId != null && attributeValue != null && !attributeId.trim().isEmpty() ){
				
				if( attributeId.trim().equals( PART_DESCRIPTION ) && !attributeValue.trim().isEmpty() ){
					partDescription = attributeValue;
				}else if( attributeId.trim().equals( PRODUCT_CLASS_DESC ) ){//原材料更新产品分级说明属性
					productClassDesc = attributeValue ;				
				}else if( attributeId.trim().equals( PART_IMCOMING ) ){
					partIncomingInspection = attributeValue;
				}else{
					setPartAttributes( attributeId , attributeValue , part , logInfo );
				}
				
			}	
		}		
		
		//保存设计视图的零部件
		part = (WTPart) PersistenceHelper.manager.save( part );
		logInfo.append(">>>>> PersistenceHelper.manager.store End......\n") ;
		
		//设置物料描述属性
		if( partDescription != null && !partDescription.trim().isEmpty() ){
			IBAUtil.forceSetIBAValue( part , PART_DESCRIPTION , partDescription );
		}
		
		//设置原材料产品分级属性			
		if( TMTypeUtil.isRawMaterial( part ) ){
			IBAUtil.forceSetIBAValue( part , PRODUCT_CLASS_DESC , productClassDesc );
		}
		//设置物料检验方式
		if( partIncomingInspection != null && !partIncomingInspection.trim().isEmpty()  ){
			IBAUtil.forceSetIBAValue( part , PART_IMCOMING , partIncomingInspection );
		}
		
		CoreUtil.checkinObject( part , "更新物料描述属性" );
		
		return part;
	}
	
	//原材料更新属性
	private static void setPartAttributes( String attributeId , String attributeValue , WTPart part , StringBuffer logInfo ) throws WTException {
		
		if( attributeId != null && attributeValue != null && part != null ){
			if( attributeId.equalsIgnoreCase("Type") ){
				
			}else if( attributeId.equalsIgnoreCase("Number") ){
				
			}else if( attributeId.equalsIgnoreCase("Name") ){
				if( part.getViewName().trim().equals( ImportConstants.D_VIEW ) ){
					setName(part, attributeValue, logInfo);
				}
			}else if( attributeId.equalsIgnoreCase("Source") ){	
				setSource(part, attributeValue, logInfo);
			}else {				

			}
		}
	}

	/**
	 * 从Excel表头中解析零部件属性的显示名称
	 * 
	 * @param sheet
	 * @return
	 */
	private static Map<Integer,String> getColumnDisplayNameMap( Sheet sheet ) {
		Map<Integer,String> columnNameMap = new HashMap<Integer,String>() ;
		
		if( sheet != null ){
			Map<Integer,String> columnInternalNameMap = getColumnInternalNameMap( sheet ) ;
			
			//ImportConstants.COLUMN_DISPLAY_NAME_ROW_INDEX为零部件属性的显示名称行的行号
			Row columnDisplayRow = sheet.getRow( ImportConstants.COLUMN_DISPLAY_NAME_ROW_INDEX ) ;
			
			if( columnDisplayRow != null ){
				Iterator<Cell> cellIte = columnDisplayRow.cellIterator() ;
				
				while( cellIte.hasNext() ){
					Cell cell = cellIte.next() ;
					
					if( cell != null ){
						int cellColumnIndex = cell.getColumnIndex() ;
						String cellValue = ImportedExcelUtil.getCellValueAsString(cell);
						
						if( cellValue == null || cellValue.equals("")){
							if( columnInternalNameMap.containsKey( cellColumnIndex )){
								
								columnNameMap.put( cellColumnIndex , columnInternalNameMap.get(cellColumnIndex) ) ;
								
							}else{
								columnNameMap.put( cellColumnIndex , cellValue ) ;
							}
						}else{
							columnNameMap.put( cellColumnIndex , cellValue ) ;
						}
					}
				}
			}
		}
		
		return columnNameMap ;
	}
	
	/**
	 * 从Excel表头中解析零部件属性的内部名称
	 * 
	 * @param sheet
	 * @return
	 */
	private static Map<Integer,String> getColumnInternalNameMap( Sheet sheet ) {
		Map<Integer,String> columnNameMap = new HashMap<Integer,String>() ;
		
		if( sheet != null ){
			//ImportConstants.COLUMN_ITERNAL_NAME_ROW_INDEX为零部件属性的内部名称行的行号
			Row columnRow = sheet.getRow( ImportConstants.COLUMN_ITERNAL_NAME_ROW_INDEX ) ;
			
			if( columnRow != null ){
				Iterator<Cell> cellIte = columnRow.cellIterator() ;
				
				while( cellIte.hasNext() ){
					Cell cell = cellIte.next() ;
					
					if( cell != null ){
						int cellColumnIndex = cell.getColumnIndex() ;
						String cellValue = ImportedExcelUtil.getCellValueAsString(cell);
						
						if( cellValue != null  ){
							cellValue = cellValue.trim() ;
							
							if( ! cellValue.isEmpty()){
								columnNameMap.put( cellColumnIndex , cellValue ) ;
							}
						}
					}
				}
			}
		}
		
		return columnNameMap ;
	}
	
	/**
	 * 根据value的值，从Map中获取对应的key值
	 * 
	 * @param NameMap
	 * @param attName
	 * @return
	 */
	public static Integer getIndex( Map<Integer,String> NameMap , String attName){
		Integer index = 0 ;
		
		Iterator<Integer> keyIte = NameMap.keySet().iterator() ;
		while( keyIte.hasNext() ){
			index = keyIte.next() ;
			String value = NameMap.get(index) ;
			
			if( value != null && value.equals( attName )){
				break ;
			}
		}
		
		return index ;
	}
	
	/**
	 * 根据零部件主数据(master)和视图获取对应最新版本零部件
	 * @author Harry Cao
	 * @param master
	 * @param view
	 * @return
	 * @throws WTException
	 */
	private static WTPart getWTPartByMasterAndView(WTPartMaster master, View view) throws WTException {
		WTPart part = null;

		//根据视图构造产品结构配置规范
		WTPartStandardConfigSpec standardConfig = WTPartStandardConfigSpec.newWTPartStandardConfigSpec(view, null);
		try {
			standardConfig.setView(view);
		} catch (WTPropertyVetoException wpve) {
			throw new WTException(wpve);
		}

		//根据master和视图获取对应最新的视图版本零部件
		QueryResult qr1 = ConfigHelper.service.filteredIterationsOf(master, standardConfig);
		if (qr1.hasMoreElements()) {
			part = (WTPart) qr1.nextElement();
		}
		return part;
	}
	
	/**
	 * 更新零部件名称属性
	 * @param part
	 * @param attributeValue
	 * @param logInfo
	 */
	private static void setName( WTPart part , String attributeValue , StringBuffer logInfo ) {
		System.out.println(">>>>>> Set Part Name......part="+ part.getDisplayIdentity()+ "...Name = " + attributeValue) ;
		
		if( (attributeValue != null) && (!attributeValue.equals("")) ){
			
			try {
				
				Identified identified = ( Identified )part.getMaster();
				WTPartMasterIdentity masteridentity = ( WTPartMasterIdentity )identified.getIdentificationObject();            
				masteridentity.setName( attributeValue );
				identified = IdentityHelper.service.changeIdentity( identified, masteridentity ); //更新名称
				PersistenceServerHelper.manager.update( part.getMaster() );

			} catch (WTPropertyVetoException e) {
				ImportedLogUtil.addPartNameInfoThrowsException( attributeValue, logInfo );
				
				e.printStackTrace();
			} catch (WTException e) {
				e.printStackTrace();
			}
		}else{
			ImportedLogUtil.addErrorPartNameInfo(attributeValue, logInfo);
		}
	}
	
	/**
	 * 更新零部件“源”属性
	 * @param part
	 * @param attributeValue
	 * @param logInfo
	 */
	private static void setSource(WTPart part, String attributeValue,StringBuffer logInfo) {
		if( (attributeValue != null) && ( !attributeValue.equals("") ) ){
			Source source = Source.toSource( attributeValue ) ;
			
			if( source != null ){
				part.setSource( source ) ;
			}else{
				ImportedLogUtil.addErrorSourceInfo(attributeValue, logInfo);
			}
		}else{
			ImportedLogUtil.addErrorSourceInfo(attributeValue, logInfo);
		}
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if( args != null && args[0] != null ){
			if ( ! RemoteMethodServer.ServerFlag ) {
				System.out.println( "Debug   RemoteMethodServer..." );
				String method = "updatePartAttributes";			
			
				try {
					RemoteMethodServer.getDefault().invoke(method, CLASSNAME, null,
							new Class[] { String.class }, new Object[] { args[0] });
					System.out.println( "Debug  end  RemoteMethodServer..." );
				} catch (RemoteException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}else{
				updatePartAttributes( args[0] ) ;
			}
		}
	}
}
